/**
 * @author Daniel Weber
 * Statische Methoden, um Daten auf den Handyspeicher zu schreiben und zu laden.
 */

import javax.microedition.rms.*; 

public class SpeicherInterface {

//-----------------RMS-SpeicherInterface----------------------------------------
static RecordStore rs=null; 
static String store = "store";
static RecordStore iDB=null; 
static String indexDB = "indexDB";
static String EMPTY="EMPTY";
static String EMPTYSTRING="avrWwrQevcze4537e645d27fA45h273";
static String separator="#";

public static boolean check(String entry){
	byte[] result = SpeicherInterface.readByteArray(entry);
	if (new String(result).equals(SpeicherInterface.EMPTY)) return false; //Kein Eintrag vorhanden
	else return true; //Eintrag existiert
}

//--------Read-Helper-----------------------------------------------------------
public static synchronized byte[] readByteArray(String entryName){ 

	byte[] result=EMPTY.getBytes(); 
	
	try{
	
		rs = RecordStore.openRecordStore(store, true); //Anlegen, wenn nicht bereits vorhanden
		int id = getID(entryName); 
		if (id!=-1) result=rs.getRecord(id);
		rs.closeRecordStore();	

	} catch(Exception e){
	 
    System.out.println("Database-Error 1: "+e.toString()); 
     
  } 
	
	return result;

}	

public static int readInteger(String entryName){
	byte[] result = readByteArray(entryName);
	return byte2int(result);
}

public static int[] readIntegerArray(String entryName){
	byte[] result = readByteArray(entryName);
	return byte2intArray(result);
}

public static long readLong(String entryName){
	byte[] result = readByteArray(entryName);
	return byte2Long(result);
}

public static boolean readBoolean(String entryName){
	byte[] result = readByteArray(entryName);
	int dummy = byte2int(result);
	if (dummy==1) return true;
	else return false;
}

public static String readString(String entryName){
  byte[] result = readByteArray(entryName);
	String str = new String(result);
	if (str.equals(EMPTYSTRING)) str="";
	return str;
}

public static byte readByte(String entryName){
	byte[] result = readByteArray(entryName);
	return result[0];
}

//--------------Write-Helper----------------------------------------------------
public static synchronized boolean writeByteArray(String entryName, byte[] values){ 
  
	try{
	
		rs = RecordStore.openRecordStore(store, true); 
		int id=getID(entryName);
		if (id>0) rs.setRecord(id, values,0,values.length); 					
		 
		else {
			id = rs.addRecord(values,0,values.length); 
			String newIdString=Integer.toString(id)+separator;  
			byte[] newId = newIdString.getBytes(); 
			byte[] newName = entryName.getBytes(); 
			byte[] newIndexEntry = concatenateArrays(newId, newName); 
			
			iDB = RecordStore.openRecordStore(indexDB, true); 
			iDB.addRecord(newIndexEntry, 0, newIndexEntry.length); 
			iDB.closeRecordStore();
		} 
	
		rs.closeRecordStore();	

	} catch(Exception e){
	 
		System.out.println("Database-Error 2: "+e.toString()); 
   
    return false; //Speichern ist fehlgeschlagen
    } 
	
	return true; //Alles OK!					

}

public static synchronized boolean writeString(String entryName, String values){  	
  if (values=="") values=EMPTYSTRING;  
  byte[] convertedValues = values.getBytes();
  return writeByteArray(entryName, convertedValues);  	
}

public static synchronized boolean writeLong(String entryName, long values){ 
  byte[] convertedValues = long2Byte(values);
  return writeByteArray(entryName, convertedValues);
}

public static synchronized boolean writeInteger(String entryName, int values){ 
	byte[] convertedValues = int2byte(values);
	return writeByteArray(entryName, convertedValues);
}

public static synchronized boolean writeBoolean(String entryName, boolean values){ 
	int dummy=0; //0 entspricht false
	if (values) dummy=1; //1 entspricht true	 
	byte[] convertedValues = int2byte(dummy);
	return writeByteArray(entryName, convertedValues);
}

public static synchronized boolean writeByte(String entryName, byte values){ 
	byte[] convertedValues = {values};
	return writeByteArray(entryName, convertedValues);
}

public static synchronized boolean writeIntegerArray(String entryName, int[] values){ 
	byte[] convertedValues = int2byteArray(values);
	return writeByteArray(entryName, convertedValues);
}

//-------------SpeicherInterface-Core----------------------------------------------------
public static synchronized void delete(String entryName){ 

  try{
  
    rs = RecordStore.openRecordStore(store, true); 
    int id = getID(entryName);
    if (id>0){
     
      rs.deleteRecord(id); 
      
      iDB = RecordStore.openRecordStore(indexDB, true); 
      RecordEnumeration re = iDB.enumerateRecords(null, null, false);      
      while (re.hasNextElement()){
        int id_iDB = re.nextRecordId(); 
        String ergebnis = new String(iDB.getRecord(id_iDB));                   
        int index=ergebnis.indexOf(separator);    
        if (index!=-1){               
          if (ergebnis.substring(index+1,ergebnis.length()).equals(entryName)){
            iDB.deleteRecord(id_iDB); 
          }
        } 
      }
      
      re.destroy();
      iDB.closeRecordStore();     
    }

    rs.closeRecordStore();  

  } catch(Exception e){
    
    System.out.println("Database-Error 3: "+e.toString()); 
    
  } 

}

private static synchronized int getID(String entryName){
	int id=-1; 
	try{
    
	iDB = RecordStore.openRecordStore(indexDB, true);   
    RecordEnumeration re = iDB.enumerateRecords(null, null, false);    
    while (re.hasNextElement()){
      String ergebnis = new String(re.nextRecord());  
      int index=ergebnis.indexOf(separator);    
      if (index!=-1){  
        if (ergebnis.substring(index+1,ergebnis.length()).equals(entryName)){
          id=Integer.parseInt(ergebnis.substring(0,index));
        }
      }      
    }
    
    re.destroy();
    iDB.closeRecordStore();  	
	} catch(Exception e){
	 
		System.out.println("Database-Error 4: "+e.toString());
    
  } 
	return id;	
}

public static synchronized String[] showAll(){
	String[] liste=null;
	try{

		iDB = RecordStore.openRecordStore(indexDB, true); //Anlegen, wenn nicht bereits vorhanden		
		RecordEnumeration re = iDB.enumerateRecords(null, null, false);
		int anzahlEntrys=iDB.getNumRecords();
		if (anzahlEntrys==0) {liste = new String[1]; liste[0]=EMPTY;}
		else liste = new String[anzahlEntrys];
		
		int indexListe=0;
		while (re.hasNextElement()){
			String ergebnis = new String(re.nextRecord());			
			int index=ergebnis.indexOf(separator);
			liste[indexListe] = ergebnis.substring(index+1);
			indexListe++;
		} 
		
		re.destroy();
		iDB.closeRecordStore();	

	} catch(Exception e){
	  
	  	System.out.println("Database-Error 5: "+e.toString());
   
  	} 
	return liste;
}

public static synchronized String[] showSelection(String suchwort){
	String[] liste=null;
	String[] ergebnisListe=null; 
	try{
		iDB = RecordStore.openRecordStore(indexDB, true); 	
		RecordEnumeration re = iDB.enumerateRecords(null, null, false);
		int anzahlEntrys=iDB.getNumRecords();
		liste = new String[anzahlEntrys];
		
		int indexListe=0;
		while (re.hasNextElement()){
			String ergebnis = new String(re.nextRecord());
			int match=ergebnis.indexOf(suchwort);
			if (match!=-1){	
	      		int index=ergebnis.indexOf(separator);
	      		liste[indexListe] = ergebnis.substring(index+1);
				indexListe++;
			}
		} 

		if (indexListe==0) {ergebnisListe = new String[1]; ergebnisListe[0]=EMPTY;} 
		else{
			int anz=0;
			for (int i=0; i<liste.length; i++){
				if (liste[i]!=null) anz++;
			}	
			ergebnisListe=new String[anz];
			for (int i=0; i<ergebnisListe.length; i++){
				if (liste[i]!=null) ergebnisListe[i]=liste[i];
			}
		}
	
		re.destroy();
		iDB.closeRecordStore();	

	} catch(Exception e){
	  
	  	System.out.println("Database-Error 6: "+e.toString()); 
	  
  	}  
  
  	return ergebnisListe;
  
}

public static synchronized void deleteAll(){
	
  try{
		RecordStore.deleteRecordStore(indexDB);
		RecordStore.deleteRecordStore(store);	
		
		System.out.println("2x RMS gel�scht");
    
  } catch(Exception e){
    
    	System.out.println("Database-Error 7: "+e.toString());
      
  } 
  
}

public static synchronized int getStorageSize(){ 
	int size=0;
	try{	
		rs = RecordStore.openRecordStore(store, true); 
		iDB = RecordStore.openRecordStore(store, true); 
	
		size+=rs.getSize();
		size+=iDB.getSize();
		
		iDB.closeRecordStore();	
		rs.closeRecordStore();	
	} catch(Exception e){
	  
		System.out.println("Database-Error 8: "+e.toString()); 
   
  	} 	
	return size;	
} 

public static synchronized int getSizeAvailable(){ 
	int size=0;
	try{
		rs = RecordStore.openRecordStore(store, true); 	
		size = rs.getSizeAvailable()-500; 
		rs.closeRecordStore();	
	} catch(Exception e){
	  
		System.out.println("Database-Error 9: "+e.toString()); 
    
  	} 	
	return size;
}

public static synchronized void debug(){
	try{
		int anzEntrys;
		rs = RecordStore.openRecordStore(store, true); 
		anzEntrys = rs.getNumRecords();
		System.out.println("Read Database, Eintr�ge: "+anzEntrys);
		    
		iDB = RecordStore.openRecordStore(store, true); 
		anzEntrys = iDB.getNumRecords();
		System.out.println("Read indexDB, Eintr�ge: "+anzEntrys);
		    
		int sizeBelegt=getStorageSize();
		System.out.println("Platzverbrauch:"+sizeBelegt);
		
  		int freeBytes=getSizeAvailable();
  		System.out.println("Freier Platz: "+freeBytes);		
		    
		RecordEnumeration re = iDB.enumerateRecords(null, null, false);
		while (re.hasNextElement()){
			byte[] b = re.nextRecord();
			String eintrag = new String(b);			
			System.out.println("iDB->"+eintrag);			
    	}
		
		rs.closeRecordStore();	
		iDB.closeRecordStore();	
	} catch(Exception e){
	  
		System.out.println("Database-Debug-Error: "+e.toString());     
  	} 	
}

//-----------Hilfsmethoden zur Konvertierung------------------------------------
public static byte[] concatenateArrays(byte[] array1, byte[] array2){
	byte[] merge = new byte[array1.length+array2.length]; 
	System.arraycopy(array1, 0, merge, 0, array1.length);
	System.arraycopy(array2, 0, merge, array1.length, array2.length);
	return merge;
}

//MSBit first = Big Endian 
public static byte[] int2byte(int v){ 
 	byte[] b = new byte[4];
 	
 	b[0]=(byte)(0xff & (v >> 24)); //MSB
 	b[1]=(byte)(0xff & (v >> 16));
 	b[2]=(byte)(0xff & (v >> 8));
 	b[3]=(byte)(0xff & v);        
	
	return b;	
}

public static int byte2int(byte[] b){
  
  if (b.length>4) System.out.println("byte2int()-Warnung: Byte-Folge enth�lt keinen Integer-Wert!");
  
	if (b.length==1) return ( ((b[0] & 0xff) << 24)  );
	if (b.length==2) return ( ((b[0] & 0xff) << 24) | ((b[1] & 0xff) << 16)  );
	if (b.length==3) return ( ((b[0] & 0xff) << 24) | ((b[1] & 0xff) << 16) |  ((b[2] & 0xff) << 8) );	
	
	return ( ((b[0] & 0xff) << 24) | ((b[1] & 0xff) << 16) |  ((b[2] & 0xff) << 8) | (b[3] & 0xff) );
}	

public static byte[] long2Byte(long l){
	byte[] array = new byte[8];	
	for ( int i = 0; i < 8 ; i++) {
		array[i] = (byte)(l >> ((7-i)*8));
	}
	return array;
}

public static long byte2Long(byte[] b){
	
  	if (b.length>8) System.out.println("byte2Long()-Warnung: Byte-Folge enth�lt keinen Long-Wert!");
  
  	long temp = 0;
	for ( int i = 0; i < 8 ; i++) {
		temp |= ((b[i]&0xFFL)<<((7-i)*8));
	}
	return temp;
}

public static byte[] int2byteArray(int[] v){ 
	byte[] b = new byte[v.length*4];
	
	int bPos=0;
	for (int i=0; i<v.length; i++){
		byte[] bPart = int2byte(v[i]);
		b[bPos] = bPart[0];
		b[bPos+1] = bPart[1];
		b[bPos+2] = bPart[2];
		b[bPos+3] = bPart[3];
		bPos+=4;
	}
	
	return b;
}

public static int[] byte2intArray(byte[] b){
	int[] ia = new int[b.length/4];
	
	int iaPos=0;
	for (int i=0; i<b.length; i+=4){
		byte[] bPart = new byte[4];
		bPart[0] = b[i];
		bPart[1] = b[i+1];
		bPart[2] = b[i+2];
		bPart[3] = b[i+3];
		
		int iPart = byte2int(bPart);
		ia[iaPos] = iPart;
		iaPos++;
	}	
	
	return ia;
	
}

}




